using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Collections;
using System.Drawing;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Design;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel.Serialization;
using System.Workflow.Runtime;
using System.Workflow.Activities;
using System.Workflow.Activities.Rules;
using System.Reflection;
using System.Diagnostics;
using System.Runtime.Serialization;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using System.Collections.Generic;

namespace OpenComposite.Workflow
{
	[Designer(typeof(LogicalEPActivityDesigner))]
	[ToolboxItem(typeof(LogicalEPActivityToolboxItem))]
	[ToolboxBitmap(typeof(resfinder), "OpenComposite.Workflow.Resources.logact_sync.png")]
	public partial class LogicalEPActivity
		: Activity, ITrackingActivity, ILogicalActivity
	{
		#region Initialization
		public LogicalEPActivity()
		{
			InitializeComponent();

			this.Canceling += new EventHandler<ActivityExecutionStatusChangedEventArgs>(LogicalEPActivity_Canceling);
			this.Compensating += new EventHandler<ActivityExecutionStatusChangedEventArgs>(LogicalEPActivity_Compensating);
		}

		#endregion

		#region Public Members

		#region Properties

		#region ActivitiesClass
		public static DependencyProperty ActivitiesClassProperty = DependencyProperty.Register(
			"ActivitiesClass", typeof(object), typeof(LogicalEPActivity), new PropertyMetadata(null));
		[Category("Logical Operation")]
		public object ActivitiesClass
		{
			get { return base.GetValue(LogicalEPActivity.ActivitiesClassProperty); }
			set { base.SetValue(LogicalEPActivity.ActivitiesClassProperty, value); }
		}
		#endregion

		#region LogicalActivityName
		public static DependencyProperty LogicalActivityNameProperty =
			DependencyProperty.Register("LogicalActivityName", typeof(string),
										typeof(LogicalEPActivity), new PropertyMetadata(null));
		[Browsable(false)]
		[Category("Logical Operation")]
		public string LogicalActivityName
		{
			get { return (string)GetValue(LogicalActivityNameProperty); }
			set { SetValue(LogicalActivityNameProperty, value); }
		}
		#endregion

		#region LogicalActivityId
		public static DependencyProperty LogicalActivityIdProperty =
			DependencyProperty.Register("LogicalActivityId", typeof(int),
										typeof(LogicalEPActivity), new PropertyMetadata(null));
		[Browsable(false)]
		[Category("Logical Operation")]
		public int LogicalActivityId
		{
			get { return (int)GetValue(LogicalActivityIdProperty); }
			set { SetValue(LogicalActivityIdProperty, value); }
		}
		#endregion

		#region Old Properties
		//#region ComponentId
		//public static DependencyProperty ComponentIdProperty =
		//    DependencyProperty.Register("ComponentId", typeof(int),
		//                                typeof(LogicalEPActivity), new PropertyMetadata(null));
		//[Category("Logical Activity")]
		//public int ComponentId
		//{
		//    get { return (int)GetValue(ComponentIdProperty); }
		//    set { SetValue(ComponentIdProperty, value); }
		//}
		//#endregion

		//#region OperationId
		//public static DependencyProperty OperationIdProperty =
		//    DependencyProperty.Register("OperationId", typeof(int),
		//                                typeof(LogicalEPActivity), new PropertyMetadata(null));
		//[Category("Logical Operation")]
		//public int OperationId
		//{
		//    get { return (int)GetValue(OperationIdProperty); }
		//    set { SetValue(OperationIdProperty, value); }
		//}
		//#endregion

		//#region InputXSLT
		//public static DependencyProperty InputXSLTProperty =
		//    DependencyProperty.Register("InputXSLT", typeof(string),
		//                                typeof(LogicalEPActivity), new PropertyMetadata(null));
		//[Category("Logical Operation")]
		//public string InputXSLT
		//{
		//    get { return (string)GetValue(InputXSLTProperty); }
		//    set { SetValue(InputXSLTProperty, value); }
		//}

		//#endregion

		//#region InputConnections
		//public static DependencyProperty InputConnectionsProperty =
		//    DependencyProperty.Register("InputConnections", typeof(string),
		//                                typeof(LogicalEPActivity), new PropertyMetadata(null));
		//[Category("Logical Operation")]
		//public string InputConnections
		//{
		//    get { return (string)GetValue(InputConnectionsProperty); }
		//    set { SetValue(InputConnectionsProperty, value); }
		//}

		//#endregion

		//#region PhysicalInputXSLT
		//public static DependencyProperty PhysicalInputXSLTProperty =
		//    DependencyProperty.Register("PhysicalInputXSLT", typeof(string),
		//                                typeof(LogicalEPActivity), new PropertyMetadata(null));
		//[Category("Logical Operation")]
		//public string PhysicalInputXSLT
		//{
		//    get { return (string)GetValue(PhysicalInputXSLTProperty); }
		//    set { SetValue(PhysicalInputXSLTProperty, value); }
		//}

		//#endregion

		//#region PhysicalInputConnections
		//public static DependencyProperty PhysicalInputConnectionsProperty =
		//    DependencyProperty.Register("PhysicalInputConnections", typeof(string),
		//                                typeof(LogicalEPActivity), new PropertyMetadata(null));
		//[Category("Logical Operation")]
		//public string PhysicalInputConnections
		//{
		//    get { return (string)GetValue(PhysicalInputConnectionsProperty); }
		//    set { SetValue(PhysicalInputConnectionsProperty, value); }
		//}

		//#endregion

		//#region SubscribedBObjects
		//public static DependencyProperty SubscribedBObjectsProperty =
		//    DependencyProperty.Register("SubscribedBObjects", typeof(string),
		//                                typeof(LogicalEPActivity), new PropertyMetadata(null));
		//[Category("Logical Operation")]
		//public string SubscribedBObjects
		//{
		//    get { return (string)GetValue(SubscribedBObjectsProperty); }
		//    set { SetValue(SubscribedBObjectsProperty, value); }
		//}

		//#endregion
		#endregion

		#endregion

		#region Methods
		#endregion

		#region Events
		#endregion

		#endregion

		#region Protected Members

		#region Methods
		// override
		protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
		{
			base.Invoke(this.ContinueAt, EventArgs.Empty);
			return ActivityExecutionStatus.Executing;
		}
		private void ContinueAt(object sender, EventArgs e)
		{
			ActivityExecutionContext context = sender as ActivityExecutionContext;
			object activitiesclass = this.ActivitiesClass;
			Type t = activitiesclass.GetType();
			if ( t != null ) {
				MethodInfo mi = t.GetMethod(this.LogicalActivityName);
				if ( mi != null ) {
					mi.Invoke(activitiesclass, new ITrackingActivity[] { this });
				}
			}
			context.CloseActivity();
		}
		protected override ActivityExecutionStatus Cancel(ActivityExecutionContext executionContext)
		{
			object activitiesclass = this.ActivitiesClass;
			Type t = activitiesclass.GetType();
			if ( t != null ) {
				MethodInfo mi = t.GetMethod(this.LogicalActivityName + "Cancel");
				if ( mi != null ) {
					mi.Invoke(activitiesclass, new ITrackingActivity[] { this });
				}
			}
			return ActivityExecutionStatus.Closed;
		}
		#endregion

		#endregion

		#region Private Members

		#region Methods
		#endregion

		#region Event Handlers

		private void LogicalEPActivity_Canceling(object sender, ActivityExecutionStatusChangedEventArgs e)
		{
		}

		private void LogicalEPActivity_Compensating(object sender, ActivityExecutionStatusChangedEventArgs e)
		{
		}

		#endregion

		#endregion

		#region ITrackingActivity Members

		public void AddKPIData(string sKPIName, string sKPIValue, string sKPIUnit, string sKPIDataType)
		{
			this.TrackData(sKPIName, new KPITrackingData(sKPIName, sKPIValue, sKPIUnit, sKPIDataType));
		}

		public void AddBusinessObjectData(string sBOName, object sBOValue)
		{
			this.TrackData(sBOName, new BusinessObjectTrackingData(sBOName, sBOValue));
		}

		#endregion
	}

	#region Class: LogicalEPActivityToolboxItem : Base: ActivityToolboxItem
	[Serializable]
	public class LogicalEPActivityToolboxItem : ActivityToolboxItem
	{
		public LogicalEPActivityToolboxItem(Type type)
			: base(type)
		{
			base.DisplayName = "Logical Operation";
		}

		private LogicalEPActivityToolboxItem(SerializationInfo info, StreamingContext context)
		{
			Deserialize(info, context);
		}
	}
	#endregion

	#region Class: LogicalEPActivityDesigner : Base: ActivityDesigner
	[ActivityDesignerTheme(typeof(LogicalEPActivityDesignerTheme))]
	public class LogicalEPActivityDesigner : ActivityDesigner
	{
		protected override void OnGiveFeedback(System.Windows.Forms.GiveFeedbackEventArgs e)
		{
			base.OnGiveFeedback(e);
		}
		protected override void OnDragOver(ActivityDragEventArgs e)
		{
			if ( e.Data.GetDataPresent(typeof(TreeNode)) ) {
				object item = ( (TreeNode)e.Data.GetData(typeof(TreeNode)) ).Tag;
				Type t = item.GetType();
				PropertyInfo pi = t.GetProperty("RepositoryItemType", BindingFlags.Instance | BindingFlags.Public);
				int rit = (int)pi.GetValue(item, null);
				if ( rit == 8 /*Operation*/ ) {
					setSelectedItem(this.Activity);
					e.Effect = DragDropEffects.Link;
				}
			}
			base.OnDragOver(e);
		}
		protected override void OnDragDrop(ActivityDragEventArgs e)
		{
			if ( e.Data.GetDataPresent(typeof(TreeNode)) ) {
				LogicalEPActivity logact = this.Activity as LogicalEPActivity;
				if ( logact != null ) {
					object item = ( (TreeNode)e.Data.GetData(typeof(TreeNode)) ).Tag;
					Type t = item.GetType();
					PropertyInfo pi = t.GetProperty("RepositoryItemType");
					int rit = (int)pi.GetValue(item, null);
					pi = t.GetProperty("ID");
					if ( rit == 8 /*Operation*/ ) {
						MethodInfo mi = t.GetMethod("AssignLogicalActivity");
						object objReturn = mi.Invoke(item, new object[] { logact.LogicalActivityId });
						if ( objReturn != null && objReturn.GetType().Name.Equals("LogicalActivity") ) {
							if ( logact.LogicalActivityId <= 0 ) {
								PropertyInfo piRetID = objReturn.GetType().GetProperty("ID");
								logact.LogicalActivityId = (int)piRetID.GetValue(objReturn, null);
								PropertyInfo piLAType = objReturn.GetType().GetProperty("LogicalActivityType");
								piLAType.SetValue(objReturn, 1/*LogicalOperation*/, null);
								MethodInfo miSave = objReturn.GetType().GetMethod("Save");
								miSave.Invoke(objReturn, null);
							}
						}
					}
					setSelectedItem(null);
					this.Initialize(logact);
					setSelectedItem(logact);
				}
			}
			base.OnDragDrop(e);
		}
		private void setSelectedItem(object item)
		{
			ISelectionService selectionService = GetService(typeof(ISelectionService)) as ISelectionService;
			if ( selectionService != null ) {
				ArrayList al = new ArrayList();
				if ( item != null )
					al.Add(item);
				selectionService.SetSelectedComponents(al);
			}
		}
	}
	#endregion

	#region Class: LogicalEPActivityDesignerTheme : Base: ActivityDesignerTheme
	public class LogicalEPActivityDesignerTheme : ActivityDesignerTheme
	{
		public LogicalEPActivityDesignerTheme(WorkflowTheme theme)
			: base(theme)
		{
			base.Initialize();
			this.BorderStyle = DashStyle.Solid;
			this.BorderColor = Color.CornflowerBlue;
			this.BackColorStart = Color.White;
			this.BackColorEnd = Color.CornflowerBlue;
			this.BackgroundStyle = LinearGradientMode.Horizontal;
			this.ForeColor = Color.Black;
		}
	}
	#endregion
}
